<?php
/** Copyright 2014 TinPhp Systems, Inc.
 * @author zhangxilian 2013-8-15
 * @package TinPhp
 */
if (!defined('IN_TINPHP')) {exit('Access Denied');}

require_once(TIN_APP_PATH . 'configs/site.sys.php');

/** TinPHP核心基础类
 * @example src/index.php 查看使用方法
 *  */
class T {
	public static $isdisplay = true;
	public static $type;
	public static $controller; // controller name	
	public static $action;
	public static $tpl;
	public static $tplFile = '';
	public static $caching = false;			//Smarty模板缓存
	public static $cache_lifetime = 1200;	//Smarty模板缓存时间(毫秒)		
	
	private $exec_startTime;
	private static $cacheId;
    /** 初始化类 
     * @param string $type 项目分组对应App/controller下的分组文件夹名称
     */
	public function __construct($type = "front") {
		$this->exec_startTime = $this->microtime_float();
		session_start();
		//$code = mt_rand(0,1000000);
		//if(!isset($_SESSION['syscode']))$_SESSION['syscode'] = $code;      //防止重复提交表单，将此随机数暂存入到session
		
		date_default_timezone_set("Asia/Shanghai");
/*
		//浏览URL地址 = "*.php/abc-abc/def-def/fff-fff";
		//$key = "abc-abc/def-def/fff-fff";
		//静态化GET参数处理
		$url = $_SERVER["REQUEST_URI"];
		$pos = strpos($url, "?", 0);
		if (IS_STATIC && !$pos)		//site.conf.php加入IS_STATIC=true定义
		{
		  $pos = strpos($url, "=", 0);
		  $key = substr($url, $pos+1);
		  $key_array = explode("/", $key);
		  $key_length = count($key_array);
		  for($i=0; $i<$key_length; $i++)
		  {
		    $key_val = explode("-", $key_array[$i]);
		    $_GET[$key_val[0]] = $key_val[1];
		    $_REQUEST[$key_val[0]] = $key_val[1];
		  }
		}
 * */
		//error_reporting(E_ALL|E_STRICT);
		//error_reporting(0);
		self::$type = $type;
		try {
			//HTML判断
			if (!self::checkHtml()) {
				return;
			}			
			self::setCtlAct();
			self::setTemplate();
			self::run();
		} catch (Exception $e) {
			//TinAppController::sysMessage("对不起，数据异常！请检查您的输入是否存在非法数据");
		}
	}
    /** 释放类，输出最终的页面结果 */
	public function __destruct() {
		self::$tpl->set("TIN_CTL", TIN_CTL);
		self::$tpl->set("TIN_ACT", TIN_ACT);
		
		$cacheId = self::$cacheId;
		if ('' === self::$tplFile) {
			self::$tplFile = self::$type.'/'.self::$controller . '/' . self::$action.'.html';
		} else {
			self::$tplFile .= ".html";
		}
		if (self::$isdisplay) {
			try {
                            if(self::$tpl){ self::$tpl->render(self::$tplFile, $cacheId);}
			} catch (SmartyException $e) {
				echo $e->__toString();
			}
		}
		
                if(@ defined(DBFactory)){
                    if(is_object(DBFactory)){DBFactory::closeDBConn();}
                }
		
//		if($_POST){
//			$code = mt_rand(0,1000000);
//			$_SESSION['syscode'] = $code;
//			echo $code;
//		}
		$time_start = $this->exec_startTime;		
		$time_end = $this->microtime_float();
		//echo '<!--'.($time_end-$time_start).' seconds-->';
	}
	
	/** 获取毫秒数 */
	public function microtime_float() {
		list ($usec, $sec) = explode(" ", microtime());
		return ((float) $usec + (float) $sec);
	}

	/**
	 * 根据URL参数设置Controller和action值
	 * format:   http[/https]://host/?ctl=[ctl]&act=[act][&other params if you want...]
	 * 默认Controller=index  默认Action=default
	 */
	protected function setCtlAct() {
		$ctl = & $_GET[TIN_CTL];
		$act = & $_GET[TIN_ACT];
		//echo $ctl.'-->'.$act;
		self::$controller = $ctl ? strtolower($ctl) : 'index';
		self::$action = $act ? strtolower($act) : 'default';
		$_GET[TIN_CTL] = self::$controller;
		$_GET[TIN_ACT] = self::$action;
	}
    /** 设置Smarty模版对象，并加载自定义标签方法
     * 可以扩展其他参数，TinPHP使用默认 */
	protected static function setTemplate() {
		if(!isset(self::$tpl)){
			require_once (TIN_APP_PATH . 'include/TinTemplate.php');		
			self::$tpl = new TinTemplate(self::$caching, self::$cache_lifetime);
			self::$tpl->addPluginsDir(TIN_APP_PATH.'app/plugins');
            //self::$tpl->left_delimiter = "{{";    //设置标签开始符
            //self::$tpl->right_delimiter = "}}";   //设置标签结束符
			//self::$tpl->force_compile = true;	//缓存文档会一直重建,只是用来调试
			//self::$tpl->debugging = true;		//输出Debug信息
			//self::$tpl->caching = false;		//设置使缓存是否可用
			//self::$tpl->cache_lifetime = 120;	//该变量定义模板缓存有效时间段的长度(单位秒)
			//self::$tpl->template_dir = "templates/";
			//self::$tpl->compile_dir  = "templates_c/";		
			//self::$tpl->removehtml_annotation = true;	//是否移除模板中html的注释
			//self::$tpl->removehtml_enter = true;	//是否移除模板中html的换行符			
		}
	}
    /** TinPHP启动方法
     * 根据Controller和Action加载app下对应类并执行方法 */
	private function run() {
		$ctlFile = TIN_APP_PATH . 'app/controller/' . self::$type . "/" . self::$controller . '.php';
		if (!file_exists($ctlFile)) {
			self::$tplFile = '404';
		} else {
			require_once $ctlFile;
			$ctlClass = ucfirst(self::$controller) . 'Controller';
			if(class_exists($ctlClass)){
				$controllerObj = new $ctlClass ();
				$method = 'action' . ucfirst(self::$action);
				if (method_exists($controllerObj, $method)) {
					return $controllerObj->$method();
				} else {
					self::$tplFile = '404';
				}
			}else{
				self::$tplFile = 'public/empty';
				exit('class ['.$ctlClass.'] not found');
			}
			
		}
	}
	
	/**
	 * 对所有提交的数据进行HTML验证过滤。
	 * */
	public static function checkHtml() {
		foreach ($_REQUEST as $key => $value) {
			if (strlen($value) != strlen(strip_tags($value))) {
				//对指定内容进行特殊HTML过滤
				if ($key == "content" || $key == "intro") {
					$news_value = $value;
					$value = preg_replace("/<(i?frame.*?)>(.*?)<(\/i?frame.*?)>/si", "", $value); //过滤frame标签
					$value = preg_replace("/<(\/?i?frame.*?)>/si", "", $value); //过滤frame标签

					$value = preg_replace("/<(noframes.*?)>(.*?)<(\/noframes.*?)>/si", "", $value); //过滤noframes标签
					$value = preg_replace("/<(\/?noframes.*?)>/si", "", $value); //过滤noframes标签
					$value = preg_replace("/<(\/?html.*?)>/si", "", $value); //过滤html标签
					$value = preg_replace("/<(\/?head.*?)>/si", "", $value); //过滤head标签
					$value = preg_replace("/<(\/?meta.*?)>/si", "", $value); //过滤meta标签
					$value = preg_replace("/<(title.*?)>(.*?)<(\/title.*?)>/si", "", $value); //过滤title标签
					$value = preg_replace("/<(\/?title.*?)>/si", "", $value); //过滤title标签

					$value = preg_replace("/<(textarea.*?)>(.*?)<(\/textarea.*?)>/si", "", $value); //过滤textarea标签
					$value = preg_replace("/<(\/?textarea.*?)>/si", "", $value); //过滤textarea标签

					$value = preg_replace("/<(input.*?)>(.*?)<(\/input.*?)>/si", "", $value); //过滤input标签
					$value = preg_replace("/<(\/?input.*?)>/si", "", $value); //过滤input标签

					$value = preg_replace("/<(\/?form.*?)>/si", "", $value); //过滤form标签

					$value = preg_replace("/<(script.*?)>(.*?)<(\/script.*?)>/si", "", $value); //过滤script标签
					$value = preg_replace("/<(\/?script.*?)>/si", "", $value); //过滤script标签
					$value = preg_replace("/vbscript/si", "", $value); //过滤script标签

					if ($value != $news_value) {
						echo "存在非法字符，无法提交.";
						return false;
					} else {
						continue;
					}
				} else {
					echo "存在非法字符，无法提交";
					return false;
				}
			}
		}
		return true;
	}	
	/** 获取Smarty指定的Cache ID 
     * @param string $param 附件参数
     * @param bool $noPrefix 是否使用目录结构设置，默认false
     */
	public static function getCacheId($param = null, $noPrefix = false) {
		if ($noPrefix) {
			self::$tpl->use_sub_dirs = true; //使用目录结构设置
		} else {
			$cacheId = self::$controller . "_" . self::$action . "_" . $_GET['domain'];
		}
		if ($param) {
			$cacheId = $cacheId . "_" . $param;
		}
		self::$cacheId = $cacheId;
		return $cacheId;
	}	
	/**
	 * 写入系统日志
	 * @param stirng $message 日志内容
	 * @param string $logLevel 日志等级类型 
     * @see TinLogger
	 */
	public static function sysLog($message, $logLevel ='debug') {
		require_once (TIN_APP_PATH . "include/TinLogger.php");
		$log = new TinLogger(SYS_LOG_PATH, 'TinCore-sysLog');
		$ip = self::getClientIP();
		$hostName = $_SERVER['REMOTE_HOST'];
		$user = $_SESSION["user"]["user_name"];
		$query = $_SERVER['QUERY_STRING'];
		//信息内容：时间 IP地址 主机名 用户名 操作（即GET提交的参数字符串）传递的消息信息
		$log->custom("$ip $hostName $user $query $message", $logLevel);        
	}
	/** 获取客户端IP，支持CDN加速时获取 */
	public static function getClientIP() {
		if (!empty ($_SERVER["HTTP_CDN_SRC_IP"])) {
			$cip = $_SERVER["HTTP_CDN_SRC_IP"];
		}
		elseif (!empty ($_SERVER["HTTP_CLIENT_IP"])) {
			$cip = $_SERVER["HTTP_CLIENT_IP"];
		}
		elseif (!empty ($_SERVER["HTTP_X_FORWARDED_FOR"])) {
			$cip = $_SERVER["HTTP_X_FORWARDED_FOR"];
		}
		elseif (!empty ($_SERVER["REMOTE_ADDR"])) {
			$cip = $_SERVER["REMOTE_ADDR"];
		} else {
			$cip = "error";
		}
		return $cip;
	}
	/** 使用phpmailer发送邮件
     * @param string $receiveEmail 接收方邮件地址
     * @param string $title 邮件标题
     * @param string $body 邮件内容
     * @param bool $ishtml 邮件是否需要html支持
     * @param string $charset 邮件编码，默认UTF-8
     * @return bool成功(true)、失败(false)
     *  */
	public static function sysSendEmail($receiveEmail, $title, $body, $ishtml=false, $charset = 'utf-8'){
		if(TIN_SYSTEM_EMAIL_SMTP=="" || TIN_SYSTEM_EMAIL_ADDRESS==""){ 
			return false; 
		}
		//发邮件通知
		require_once(TIN_APP_PATH."include/utils/phpmailer/class.phpmailer.php");
		$mail = new PHPMailer();   //实例化
        $mail->IsSMTP();                 // 启用SMTP
        $mail->Host = TIN_SYSTEM_EMAIL_SMTP;      //smtp服务器的名称（这里以126邮箱为例）
        $mail->SMTPAuth = TIN_SYSTEM_EMAIL_SMTP_AUTH;         //启用smtp认证
        $mail->Username = TIN_SYSTEM_EMAIL_ADDRESS;
        $mail->Password = TIN_SYSTEM_EMAIL_PASSWORD;
        $mail->From = TIN_SYSTEM_EMAIL_ADDRESS;            //发件人地址（也就是你的邮箱地址）
        $mail->FromName = TIN_SYSTEM_EMAIL_TRUENAME;              //发件人姓名
        $mail->AddAddress($receiveEmail); //添加收件人
        //$mail->WordWrap = 100;                    //设置每行字符长度
        $mail->IsHTML($ishtml);                 // 是否HTML格式邮件
        $mail->CharSet=$charset;    //设置邮件编码
        $mail->Subject = $title;          //邮件主题
        $mail->Body    = $body; //邮件正文不支持HTML的备用显示
        if(!$mail->Send()){
        	Y :: sysLog("邮件通知失败：".$mail->Body);
        	return false;
        }
        return true;
	}

} //End Class
?>